package com.engine.salary.util.excel;

import cn.hutool.core.util.StrUtil;
import com.engine.salary.component.WeaTableColumnGroup;
import com.engine.salary.util.SalaryDateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import weaver.wechat.util.Utils;

import java.awt.Color;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ExcelUtilPlus {
    /**
     * 生成excel
     *
     * @param rowList
     * @return
     */
    public static XSSFWorkbook genWorkbook(List<List<String>> rowList, String sheetName) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);

        for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
            List<String> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex);
            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);
                cell.setCellType(CellType.STRING);
                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    cell.setCellStyle(cellStyle);
                }
                cell.setCellValue(infoList.get(cellIndex));
//                sheet.setColumnWidth(cellIndex, 35 * 256);
            }
        }
        return workbook;
    }


    public static XSSFWorkbook genWorkbookV2WithPattern(List<List<Object>> rowList, String sheetName, boolean lastRowRed) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFCellStyle redCellStyle = workbook.createCellStyle();
        XSSFFont redFont = workbook.createFont();
        redFont.setFontName("宋体");
        redFont.setFontHeightInPoints((short) 10);// 设置字体大小
        redFont.setColor(new XSSFColor(new Color(0xFF3333), null));
        redFont.setBold(true);
        redCellStyle.setWrapText(true);
        redCellStyle.setFont(redFont);// 选择需要用到的字体格式
        redCellStyle.setBorderLeft(BorderStyle.THIN);
        redCellStyle.setBorderRight(BorderStyle.THIN);
        redCellStyle.setBorderTop(BorderStyle.THIN);
        redCellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);
        //遍历设置列宽
        List<Object> header = rowList.get(0);
        List<Integer> patternList = new ArrayList<>();
        XSSFRow row0 = sheet.createRow(0);
        for (int i = 0; i < header.size(); i++) {
            WeaTableColumnGroup columnGroupItem = (WeaTableColumnGroup) header.get(i);
            XSSFCell rowZeroCell = row0.createCell(i, CellType.STRING);
            rowZeroCell.setCellValue(columnGroupItem.getText());
            rowZeroCell.setCellStyle(titleCellStyle);
            //设置列宽
            sheet.setColumnWidth(i, Math.min(255, Math.max(12, Utils.null2String(columnGroupItem.getText()).length() * 4)) * 256);
            patternList.add(columnGroupItem.getPattern());
        }

        HashMap<Integer, XSSFCellStyle> numberCellStyleMap = new HashMap<Integer, XSSFCellStyle>();
        HashMap<Integer, XSSFCellStyle> numberRedCellStyleMap = new HashMap<Integer, XSSFCellStyle>();
        XSSFDataFormat df = workbook.createDataFormat();
        patternList.stream().distinct().filter(a -> a != null).forEach(p -> {
            String start = "0.";
            if (p == 0) {
                start = "0";
            }

            XSSFCellStyle numberRedCellStyle = workbook.createCellStyle();
            // 不能copy，在excel里编辑时背景变成了黑色
            // BeanUtils.copyProperties(redCellStyle, numberRedCellStyle);
            numberRedCellStyle.setWrapText(true);
            numberRedCellStyle.setBorderLeft(BorderStyle.THIN);
            numberRedCellStyle.setBorderRight(BorderStyle.THIN);
            numberRedCellStyle.setBorderTop(BorderStyle.THIN);
            numberRedCellStyle.setBorderBottom(BorderStyle.THIN);
            numberRedCellStyle.setFont(redFont);
            short format = df.getFormat(start + Stream.generate(() -> "0").limit(p).collect(Collectors.joining()) + "_ ");
            numberRedCellStyle.setDataFormat(format);
            numberRedCellStyleMap.put(p, numberRedCellStyle);
            XSSFCellStyle numberCellStyle = workbook.createCellStyle();
            // BeanUtils.copyProperties(cellStyle, numberCellStyle);
            numberCellStyle.setFont(font);// 选择需要用到的字体格式
            numberCellStyle.setWrapText(true);
            numberCellStyle.setBorderLeft(BorderStyle.THIN);
            numberCellStyle.setBorderRight(BorderStyle.THIN);
            numberCellStyle.setBorderTop(BorderStyle.THIN);
            numberCellStyle.setBorderBottom(BorderStyle.THIN);
            numberCellStyle.setDataFormat(format);
            numberCellStyleMap.put(p, numberCellStyle);
        });

        for (int rowIndex = 1; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);
                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    if (lastRowRed && rowIndex == rowList.size() - 1) {
                        cell.setCellStyle(redCellStyle);
                    } else {
                        cell.setCellStyle(cellStyle);
                    }
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    if (StrUtil.isNotBlank(String.valueOf(o))) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    }
                } else if (o instanceof BigDecimal) {
                    if (lastRowRed && rowIndex == rowList.size() - 1) {
                        cell.setCellStyle(numberRedCellStyleMap.get(patternList.get(cellIndex)));
                    } else {
                        cell.setCellStyle(numberCellStyleMap.get(patternList.get(cellIndex)));
                    }
                    cell.setCellType(CellType.NUMERIC);
                    cell.setCellValue(((BigDecimal) o).doubleValue());
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(o == null ? "" : o.toString());
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }

    public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);
        //遍历设置列宽
        List<Object> header = rowList.get(0);
        for (int i = 0; i < header.size(); i++) {
            sheet.setColumnWidth(i, Math.min(255, Math.max(12, header.get(i).toString().length() * 4)) * 256);
        }

        for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);
                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    cell.setCellStyle(cellStyle);
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    if (StrUtil.isNotBlank(String.valueOf(o))) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    }
                } else if (o instanceof BigDecimal) {
                    cell.setCellType(CellType.NUMERIC);
                    cell.setCellValue(((BigDecimal) o).doubleValue());
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(o == null ? "" : o.toString());
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }


    public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName, List<ExcelComment> comments) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);

        //遍历设置列宽
        List<Object> header = rowList.get(0);
        for (int i = 0; i < header.size(); i++) {
            sheet.setColumnWidth(i, Math.min(255, Math.max(12, header.get(i).toString().length() * 4)) * 256);
        }

        for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);
                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    cell.setCellStyle(cellStyle);
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    if (StrUtil.isNotBlank(String.valueOf(o))) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    }
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(String.valueOf(o));
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }

        if (CollectionUtils.isNotEmpty(comments)) {
            for (ExcelComment c : comments) {
                XSSFDrawing patr = sheet.createDrawingPatriarch();
                XSSFComment cellComment = patr.createCellComment(new XSSFClientAnchor(c.dx1, c.dy1, c.dx2, c.dy2, c.col1, c.row1, c.col2, c.row2));
                cellComment.setString(c.content);
            }
        }
        return workbook;
    }

    public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName, boolean lastRowRed) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);

        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);

        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFCellStyle redCellStyle = workbook.createCellStyle();
        XSSFFont redFont = workbook.createFont();
        redFont.setFontName("宋体");
        redFont.setFontHeightInPoints((short) 10);// 设置字体大小
        redFont.setColor(new XSSFColor(new Color(0xFF3333), null));
        redFont.setBold(true);
        redCellStyle.setWrapText(true);
        redCellStyle.setFont(redFont);// 选择需要用到的字体格式

        redCellStyle.setBorderLeft(BorderStyle.THIN);
        redCellStyle.setBorderRight(BorderStyle.THIN);
        redCellStyle.setBorderTop(BorderStyle.THIN);
        redCellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);

        //遍历设置列宽
        List<Object> header = rowList.get(0);
        for (int i = 0; i < header.size(); i++) {
            sheet.setColumnWidth(i, Math.min(255, Math.max(12, header.get(i).toString().length() * 4)) * 256);
        }

        for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);
                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    if (lastRowRed && rowIndex == rowList.size() - 1) {
                        cell.setCellStyle(redCellStyle);
                    } else {
                        cell.setCellStyle(cellStyle);
                    }
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    if (StrUtil.isNotBlank(String.valueOf(o))) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    }
                } else if (o instanceof BigDecimal) {
                    cell.setCellType(CellType.NUMERIC);
                    cell.setCellValue(((BigDecimal) o).doubleValue());
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(o == null ? "" : o.toString());
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }

    // 数值项目修改excel单元格格式为数值
    public static XSSFWorkbook genWorkbookWithChildTitleColumnWithExcelFormat(List<List<Object>> rowList, String sheetName, boolean lastRowRed) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFCellStyle childTitleCellStyle = workbook.createCellStyle();
        childTitleCellStyle.setFont(titleFont);
        childTitleCellStyle.setAlignment(HorizontalAlignment.LEFT);
        childTitleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        childTitleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        childTitleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        childTitleCellStyle.setBorderLeft(BorderStyle.THIN);
        childTitleCellStyle.setBorderRight(BorderStyle.THIN);
        childTitleCellStyle.setBorderTop(BorderStyle.THIN);
        childTitleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);

        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFCellStyle redCellStyle = workbook.createCellStyle();
        XSSFFont redFont = workbook.createFont();
        redFont.setFontName("宋体");
        redFont.setFontHeightInPoints((short) 10);// 设置字体大小
        redFont.setColor(new XSSFColor(new Color(0xFF3333), null));
        redFont.setBold(true);
        redCellStyle.setWrapText(true);
        redCellStyle.setFont(redFont);// 选择需要用到的字体格式

        redCellStyle.setBorderLeft(BorderStyle.THIN);
        redCellStyle.setBorderRight(BorderStyle.THIN);
        redCellStyle.setBorderTop(BorderStyle.THIN);
        redCellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);

        //处理合并单元格
        XSSFRow row0 = sheet.createRow(0);
        XSSFRow row1 = sheet.createRow(1);

        // 保留小数位数
        List<Integer> patternList = new ArrayList<>();
        List<Object> header = rowList.get(0);
        int startIndex = 0;
        for (int i = 0; i < header.size(); i++) {
            WeaTableColumnGroup columnGroupItem = (WeaTableColumnGroup) header.get(i);
            if (columnGroupItem.getChildren() == null) {
                sheet.addMergedRegion(new CellRangeAddress(0, 1, startIndex, startIndex));

                XSSFCell rowZeroCell = row0.createCell(startIndex, CellType.STRING);
                rowZeroCell.setCellValue(columnGroupItem.getText().toString());
                rowZeroCell.setCellStyle(titleCellStyle);
                XSSFCell rowOneCell = row1.createCell(startIndex, CellType.STRING);
                rowOneCell.setCellValue(columnGroupItem.getText().toString());
                rowOneCell.setCellStyle(titleCellStyle);
                //设置列宽
                sheet.setColumnWidth(startIndex, Math.min(255, Math.max(12, columnGroupItem.getText().length() * 4)) * 256);
                startIndex++;
                patternList.add(columnGroupItem.getPattern());
            } else {
                List<WeaTableColumnGroup> childrenList = columnGroupItem.getChildren();
                int endIndex = startIndex + childrenList.size() - 1;

                if (endIndex > startIndex) {
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex));
                }

                XSSFCell cell = row0.createCell(startIndex, CellType.STRING);
                cell.setCellValue(columnGroupItem.getText().toString());
                cell.setCellStyle(childTitleCellStyle);

                for (int j = 0; j < childrenList.size(); j++) {
                    WeaTableColumnGroup childrenItem = (WeaTableColumnGroup) childrenList.get(j);

                    XSSFCell subHeader = row1.createCell(startIndex + j, CellType.STRING);
                    subHeader.setCellValue(childrenItem.getText().toString());
                    subHeader.setCellStyle(titleCellStyle);
                    //设置列宽
                    sheet.setColumnWidth(startIndex + j, Math.min(255, Math.max(12, childrenItem.getText().length() * 4)) * 256);
                    patternList.add(childrenItem.getPattern());
                }

                startIndex += childrenList.size();

            }

        }

        HashMap<Integer, XSSFCellStyle> numberCellStyleMap = new HashMap<Integer, XSSFCellStyle>();
        HashMap<Integer, XSSFCellStyle> numberRedCellStyleMap = new HashMap<Integer, XSSFCellStyle>();
        XSSFDataFormat df = workbook.createDataFormat();
        patternList.stream().distinct().filter(a -> a != null).forEach(p -> {
            String start = "0.";
            if (p == 0) {
                start = "0";
            }
            XSSFCellStyle numberRedCellStyle = workbook.createCellStyle();
            // 不能copy，在excel里编辑时背景变成了黑色
            // BeanUtils.copyProperties(redCellStyle, numberRedCellStyle);
            numberRedCellStyle.setWrapText(true);
            numberRedCellStyle.setBorderLeft(BorderStyle.THIN);
            numberRedCellStyle.setBorderRight(BorderStyle.THIN);
            numberRedCellStyle.setBorderTop(BorderStyle.THIN);
            numberRedCellStyle.setBorderBottom(BorderStyle.THIN);
            numberRedCellStyle.setFont(redFont);
            short format = df.getFormat(start + Stream.generate(() -> "0").limit(p).collect(Collectors.joining()) + "_ ");
            numberRedCellStyle.setDataFormat(format);
            // 最后一行红色
            numberRedCellStyleMap.put(p, numberRedCellStyle);
            XSSFCellStyle numberCellStyle = workbook.createCellStyle();
            // BeanUtils.copyProperties(cellStyle, numberCellStyle);
            numberCellStyle.setFont(font);// 选择需要用到的字体格式
            numberCellStyle.setWrapText(true);
            numberCellStyle.setBorderLeft(BorderStyle.THIN);
            numberCellStyle.setBorderRight(BorderStyle.THIN);
            numberCellStyle.setBorderTop(BorderStyle.THIN);
            numberCellStyle.setBorderBottom(BorderStyle.THIN);

            numberCellStyle.setDataFormat(format);
            numberCellStyleMap.put(p, numberCellStyle);
        });

        for (int rowIndex = 1; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex + 1);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);

                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    if (lastRowRed && rowIndex == rowList.size() - 1) {
                        cell.setCellStyle(redCellStyle);
                    } else {
                        cell.setCellStyle(cellStyle);
                    }
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    if (StrUtil.isNotBlank(String.valueOf(o))) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    }
                } else if (o instanceof BigDecimal) {
                    if (lastRowRed && rowIndex == rowList.size() - 1) {
                        cell.setCellStyle(numberRedCellStyleMap.get(patternList.get(cellIndex)));
                    } else {
                        cell.setCellStyle(numberCellStyleMap.get(patternList.get(cellIndex)));
                    }
                    cell.setCellType(CellType.NUMERIC);
                    double value = o == null ? 0 : ((BigDecimal) o).doubleValue();
                    cell.setCellValue(value);
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(o == null ? "" : o.toString());
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }

    public static XSSFWorkbook genWorkbookWithChildTitleColumn(List<List<Object>> rowList, String sheetName, boolean lastRowRed) {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFCellStyle childTitleCellStyle = workbook.createCellStyle();
        childTitleCellStyle.setFont(titleFont);
        childTitleCellStyle.setAlignment(HorizontalAlignment.LEFT);
        childTitleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        childTitleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        childTitleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        childTitleCellStyle.setBorderLeft(BorderStyle.THIN);
        childTitleCellStyle.setBorderRight(BorderStyle.THIN);
        childTitleCellStyle.setBorderTop(BorderStyle.THIN);
        childTitleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);

        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setFillPattern(FillPatternType.NO_FILL);

        XSSFCellStyle redCellStyle = workbook.createCellStyle();
        XSSFFont redFont = workbook.createFont();
        redFont.setFontName("宋体");
        redFont.setFontHeightInPoints((short) 10);// 设置字体大小
        redFont.setColor(new XSSFColor(new Color(0xFF3333), null));
        redFont.setBold(true);
        redCellStyle.setWrapText(true);
        redCellStyle.setFont(redFont);// 选择需要用到的字体格式

        redCellStyle.setBorderLeft(BorderStyle.THIN);
        redCellStyle.setBorderRight(BorderStyle.THIN);
        redCellStyle.setBorderTop(BorderStyle.THIN);
        redCellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);

        //处理合并单元格
        XSSFRow row0 = sheet.createRow(0);
        XSSFRow row1 = sheet.createRow(1);
        List<Object> header = rowList.get(0);
        int startIndex = 0;
        for (int i = 0; i < header.size(); i++) {
            WeaTableColumnGroup columnGroupItem = (WeaTableColumnGroup) header.get(i);
            if (columnGroupItem.getChildren() == null) {
                sheet.addMergedRegion(new CellRangeAddress(0, 1, startIndex, startIndex));

                XSSFCell rowZeroCell = row0.createCell(startIndex, CellType.STRING);
                rowZeroCell.setCellValue(columnGroupItem.getText().toString());
                rowZeroCell.setCellStyle(titleCellStyle);
                XSSFCell rowOneCell = row1.createCell(startIndex, CellType.STRING);
                rowOneCell.setCellValue(columnGroupItem.getText().toString());
                rowOneCell.setCellStyle(titleCellStyle);
                //设置列宽
                sheet.setColumnWidth(startIndex, Math.min(255, Math.max(12, columnGroupItem.getText().length() * 4)) * 256);
                startIndex++;
            } else {
                List<WeaTableColumnGroup> childrenList = columnGroupItem.getChildren();
                int endIndex = startIndex + childrenList.size() - 1;

                if (endIndex > startIndex) {
                    sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex));
                }

                XSSFCell cell = row0.createCell(startIndex, CellType.STRING);
                cell.setCellValue(columnGroupItem.getText().toString());
                cell.setCellStyle(childTitleCellStyle);

                for (int j = 0; j < childrenList.size(); j++) {
                    WeaTableColumnGroup childrenItem = (WeaTableColumnGroup) childrenList.get(j);

                    XSSFCell subHeader = row1.createCell(startIndex + j, CellType.STRING);
                    subHeader.setCellValue(childrenItem.getText().toString());
                    subHeader.setCellStyle(titleCellStyle);
                    //设置列宽
                    sheet.setColumnWidth(startIndex + j, Math.min(255, Math.max(12, childrenItem.getText().length() * 4)) * 256);
                }

                startIndex += childrenList.size();

            }

        }

        for (int rowIndex = 1; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex + 1);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);

                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    if (lastRowRed && rowIndex == rowList.size() - 1) {
                        cell.setCellStyle(redCellStyle);
                    } else {
                        cell.setCellStyle(cellStyle);
                    }
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    if (StrUtil.isNotBlank(String.valueOf(o))) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    }
                } else if (o instanceof BigDecimal) {
                    cell.setCellType(CellType.NUMERIC);
                    cell.setCellValue(o == null ? 0 : ((BigDecimal) o).doubleValue());
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(SalaryDateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(o == null ? "" : o.toString());
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }

    public static float getFinalHeight(Object o, int width, float finalHeight, float height) {
        if (o != null && getStrlength(o.toString()) > width) {
            float remainder = getStrlength(o.toString()) % width;
            int multiple = getStrlength(o.toString()) / width;
            int finalMultiple = remainder > 0 ? (multiple + 1) : multiple;
            float compareHeight = height * finalMultiple;
            finalHeight = Math.max(finalHeight, compareHeight);
        }
        return finalHeight;
    }

    public static int getStrlength(String str) {
        int strLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        /* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
        for (int i = 0; i < str.length(); i++) {
            /* 从字符串中获取一个字符 */
            String temp = str.substring(i, i + 1);
            /* 判断是否为中文字符 */
            if (temp.matches(chinese)) {
                /* 中文字符长度为2 */
                strLength += 2;
            } else {
                /* 其他字符长度为1 */
                strLength += 1;
            }
        }
        return strLength;
    }

}
